#include "RingQueue.hpp"
#include "Thread.hpp"
#include <vector>
#include<string>
#include"Task.hpp"
#include <ctime>
using namespace std;
using namespace ThreadModule;


using ringqueue_t = RingQueue<Task>;
class ThreadData
{
public:
private:
   ringqueue_t &bq;
    string who;
};
void Consumer(ringqueue_t &rq,string name)
{
    while (1)
    {
        sleep(2);
        Task t=0;
        rq.Pop(&t);
      cout<<"consumer handler task :"<<"["<<name<<"]"<<endl;
      t();
     // sleep(1);
    }
}
void Productor(ringqueue_t &rq, string name)
{
    srand(time(nullptr) ^ pthread_self());
    while (1)
    {
         //sleep(1);
        rq.Enqueue(Download);
        cout<<"productor : "<<"["<<name<<"]"<<endl;
    }
}

void InitComm(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq, func_t<ringqueue_t> func)
{
    for (int i = 0; i < num; i++)
    {
        string name = "thread-" + to_string(i + 1);
        threads->emplace_back(func, rq, name);
    }
}
void InitConsumer(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{

   InitComm(threads, num, rq, Consumer);
}

void InitProduct(vector<Thread<ringqueue_t>> *threads, int num, ringqueue_t &rq)
{
   InitComm(threads, num, rq, Productor);
}

void WaitAllThread(vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}
 void StartAll(vector<Thread<ringqueue_t>> &threads)
 {
     for (auto &thread : threads)
    {
       cout<<"start"<<thread.name()<<endl;
       thread.Start();
    }
 }
int main()
{
   ringqueue_t *rq = new ringqueue_t(10);
    vector<Thread<ringqueue_t>> threads;
    InitConsumer(&threads, 1, *rq);
   InitProduct(&threads, 1, *rq);
   StartAll(threads);
    WaitAllThread(threads);
}